package org.example.gc;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class ReferenceType {
	
	private static ReferenceQueue<User> rq = new ReferenceQueue<User>();
			
	private static void printQueue(String str) {
		Reference<? extends User> obj = rq.poll();
		if(obj!=null) {
			System.out.println("the gc Ojbect reference=="+str+" = "+obj.get());
		}
	}
	
	private static void testSoftReference()throws Exception {
		List<SoftReference<User>> list = new ArrayList<SoftReference<User>>();
		
		for(int i=0;i<10;i++) {
			SoftReference<User> sr = new SoftReference<User>(new User("soft "+i),rq);
			
			System.out.println("now the soft user==="+sr.get());
			
			list.add(sr);
		}
		
		System.gc();
		
		Thread.sleep(1000L);
		
		printQueue("soft");
	}
	
	private static void testWeakReference()throws Exception {
		List<WeakReference<User>> list = new ArrayList<WeakReference<User>>();
		
		for(int i=0;i<10;i++) {
			WeakReference<User> sr = new WeakReference<User>(new User("weak "+i),rq);
			
			System.out.println("now the weak user==="+sr.get());
			
			list.add(sr);
		}
		
		System.gc();
		
		Thread.sleep(1000L);
		
		printQueue("weak");
	}
	
	private static void testPhantomReference()throws Exception {
		List<PhantomReference<User>> list = new ArrayList<PhantomReference<User>>();
		
		for(int i=0;i<10;i++) {
			PhantomReference<User> sr = new PhantomReference<User>(new User("Phantom "+i),rq);
			
			System.out.println("now the Phantom user==="+sr.get());
			
			list.add(sr);
		}
		
		System.gc();
		
		Thread.sleep(1000L);
		
		printQueue("Phantom");
	}
	
	public static void main(String[] args)throws Exception {
		// SoftReference 软引用在内存充足情况不会被回收，当内存不足时会回收软引用垃圾
		testSoftReference(); //35k作用不发生回收

		// WeakReference 弱引用在垃圾回收时会被回收
		testWeakReference();
		//PhantomReference 虚引用在垃圾回收时一定会被回收
		testPhantomReference();
	}
}
